#include "oxc.h"
#include "part.h"
#include "common.h"

static oxc_device oxc;

#define OXC_BUF_LENGTH  1024
#define OXC_CONFIG_FILE "16*16"
#define OXC_CONFIG_FILE_BACK "16*16_back"

char* oxc_file = "./config/oxc_config";
char* oxc_file_back = "./config/oxc_config_bak";

void oxc_sample_timer(void* param);
int set_atten_abs(oxc_device* p_oxc,int* channel_list,int size,float atten,clock_t* p_time);
int set_baudrate(oxc_device* p_oxc);
int set_baudrate_oxc(oxc_device* p_oxc,int baudrate);

typedef struct _atten_list{
    float atten;
    int channel_list[OXC_CHANNEL_NUMBER];
}atten_list;

int init_oxc_device(oxc_device* p_oxc){
    p_oxc->busy = 1;
    load_config_oxc(p_oxc,OXC_CONFIG_FILE);
    p_oxc->busy = 0;
}

void init_oxc(oxc_device* p_oxc){
    if(p_oxc == NULL) return;
    memset(p_oxc,0,sizeof(oxc_device));
    p_oxc->uart_fd = open_uart("/dev/ttymxc5",38400,8,'N',1);
    p_oxc->timer = timer_start(oxc_sample_timer,SAMPLE_TIME,p_oxc,1);
    p_oxc->print_flag = print_oxc;
    p_oxc->device_name = "oxc";
}

int set_baudrate(oxc_device* p_oxc){
    int ret;
    char buff[OXC_BUF_LENGTH] = {0};
    int baunrate[4] = {115200,9600,19200},i=0;
 
    while((ret = query_tty((device*)p_oxc,"*idn?",strlen("*idn?"),buff,OXC_BUF_LENGTH,5,0)) == 0 && i < 4){        
        set_speed_uart(p_oxc->uart_fd,baunrate[i++]);
    }
    if(ret > 0 && i > 0){
        set_baudrate_oxc(p_oxc,38400);
        set_speed_uart(p_oxc->uart_fd,38400);
    }
    return ret;
}

void oxc_save_config(oxc_device* p_oxc, int is_back){
    FILE* fp;
    int size = 0;
    if(is_back){
        fp = fopen(oxc_file_back,"w");
    }
    else{
        fp = fopen(oxc_file,"w");
    }
    if(fp == NULL) return;
    size = OFFSET(oxc_device,save_end) - OFFSET(oxc_device,save_begin);
    fwrite((void*)&p_oxc->save_begin,size,1,fp);
    fclose(fp);
}

int oxc_load_config(oxc_device* p_oxc, int is_back){
    FILE* fp;
    int size = 0;
    char cmd[64] = {0};
    if(is_back){
        fp = fopen(oxc_file_back,"r");
        if(fp){
            sprintf(cmd,"cp %s %s",oxc_file_back,oxc_file);
            system(cmd);
        }
    }
    else{
        fp = fopen(oxc_file,"r");
    }
    if(fp == NULL) return 0;
    size = OFFSET(oxc_device,save_end) - OFFSET(oxc_device,save_begin);
    fread((void*)&p_oxc->save_begin,size,1,fp);
    fclose(fp);
    return 1;
}

void oxc_alarm_register(device_alarm_list* p_list){
    alram_info_register(p_list,&oxc.alarm_info.fanw,"a cooling fan is failing","fanw","oxc");
    alram_info_register(p_list,&oxc.alarm_info.fanf,"a cooling fan has failed","fanf","oxc");
    alram_info_register(p_list,&oxc.alarm_info.fpga,"an FPGA programming error","fpga","oxc");
    alram_info_register(p_list,&oxc.alarm_info.conf,"a switch configuration error","conf","oxc");
    alram_info_register(p_list,&oxc.alarm_info.temp,"temperature has gone out of range","temp","oxc");
}

cJSON* oxc_packet(int id,int error_code,cJSON* param,int time){
    return response_packet(id,error_code,param,time);
}

int set_baudrate_oxc(oxc_device* p_oxc,int baudrate){
    char buff[128] = ":syst:comm:ser:baud ";
    int opc = 0;
    sprintf(buff+strlen(buff),"%d;*ipc;*ipc?",baudrate);
    query_tty((device*)p_oxc,buff,strlen(buff),(char*)&opc,4,5,0); 
    return opc;
}

void oxc_sample(oxc_device* p_oxc){
    uint16_t status;
    char buff[] = "stat:alar?";
    int ret;
    if(p_oxc->busy) return;
    p_oxc->busy = 1;
    ret = query_tty((device*)p_oxc,buff,strlen(buff),(char*)&status,2,5,0); 
    if(ret == 2){
        p_oxc->alarm_info.fanw = (ret>>4)&0x1;
        p_oxc->alarm_info.fanf = (ret>>5)&0x1;
        p_oxc->alarm_info.fpga = (ret>>6)&0x1;
        p_oxc->alarm_info.conf = (ret>>7)&0x1;
        p_oxc->alarm_info.temp = (ret>>8)&0x1;
    } 
    p_oxc->busy = 0;
}

void oxc_sample_timer(void* param){
    oxc_device* p_oxc = (oxc_device*)param;
    p_oxc->sample_flag = 1;
}

cJSON* oxc_custom_packet(oxc_device* p_oxc){
    cJSON* param = cJSON_CreateObject();    
    cJSON_AddItemToObject(param,"in",cJSON_CreateIntArray(p_oxc->in_port,p_oxc->in_count));
    cJSON_AddItemToObject(param,"out",cJSON_CreateIntArray(p_oxc->out_port,p_oxc->out_count));              
    return param;  
}

int load_config_oxc(oxc_device* p_oxc,char* fname){
    int ret;
    char buff[OXC_BUF_LENGTH] = {0};
    
    sprintf(buff,":sct:conf:load \"%s\";",fname);
    write_tty((device*)p_oxc,buff,strlen(buff));
    return 1; 
}

int stroe_config_oxc(oxc_device* p_oxc,char* fname){
    int ret;
    char buff[OXC_BUF_LENGTH] = {0};

    sprintf(buff,":sct:conf:stor \"%s\";",fname);
    write_tty((device*)p_oxc,buff,strlen(buff));
    return 1;      
}

int set_port_oxc(oxc_device* p_oxc,clock_t* p_time){
    int ret;
    char buff[OXC_BUF_LENGTH] = {0};
    char s_in[128] = {0};
    char s_out[128] = {0};
    array_to_string(p_oxc->in_port, p_oxc->in_count,0,s_in,0);
    array_to_string(p_oxc->out_port, p_oxc->out_count,0,s_out,0);
    sprintf(buff,":oxc:swit:conn:only (@%s),(@%s);stat",s_in,s_out);
    ret = query_tty_time((device*)p_oxc,buff,strlen(buff),buff,OXC_BUF_LENGTH,5,0,p_time); 
    if(ret > 0){
        if(find_keys("\\(@([0-9]+,[0-9]+,[0-9]+)\\),\\(@([0-9]+,[0-9]+,[0-9]+)\\)",
                                buff,
                                2,
                                s_in,
                                s_out)){
            string_to_array(s_in,p_oxc->in_port,&p_oxc->in_count,0);
            string_to_array(s_out,p_oxc->out_port,&p_oxc->out_count,0);
            stroe_config_oxc(p_oxc,OXC_CONFIG_FILE);  
            // oxc_save_config(p_oxc,0);                                    
            return 1;            
        }        
    }   
    return 0;
}

cJSON* set_custom_oxc(oxc_device* p_oxc,cJSON* param){
    cJSON *item,*array;
    clock_t time;
    int ret,size,i,j=0;

    array = cJSON_GetObjectItem(param,"in");
    if(array){
        size = cJSON_GetArraySize(array);
        for(i=0;i<size;i++){
            item = cJSON_GetArrayItem(array,i);
            if(item){
                p_oxc->in_port[j++],item->valueint;
            }
        }
    }
    p_oxc->in_count = j;
    j = 0;
    array = cJSON_GetObjectItem(param,"out");
    if(array){
        size = cJSON_GetArraySize(array);
        for(i=0;i<size;i++){
            item = cJSON_GetArrayItem(array,i);
            if(item){
                p_oxc->out_port[j++],item->valueint;
            }
        }
    }
    p_oxc->out_count = j;

    if(set_port_oxc(p_oxc,&time)){
        return oxc_packet(id_oxc_set_custom,NO_ERROR,oxc_custom_packet(p_oxc),time); 
    }            
    return oxc_packet(id_oxc_set_custom,COMM_TIMEOUT,NULL,0);     
}

cJSON* get_custom_oxc(oxc_device* p_oxc){
    int ret;
    char buff[OXC_BUF_LENGTH] = {0};
    char s_in[128] = {0};
    char s_out[128] = {0};

    sprintf(buff,":oxc:swit:conn:stat?");
    ret = query_tty((device*)p_oxc,buff,strlen(buff),buff,OXC_BUF_LENGTH,5,0);    
    if(ret > 0){
        if(find_keys("\\(@([0-9]+,[0-9]+,[0-9]+)\\),\\(@([0-9]+,[0-9]+,[0-9]+)\\)",
                                buff,
                                2,
                                s_in,
                                s_out)){
            string_to_array(s_in,p_oxc->in_port,&p_oxc->in_count,0);
            string_to_array(s_in,p_oxc->out_port,&p_oxc->out_count,0);                                                   
            return oxc_packet(id_oxc_set_custom,NO_ERROR,oxc_custom_packet(p_oxc),0);            
        }        
    }            
    return oxc_packet(id_oxc_set_custom,COMM_TIMEOUT,NULL,0); 
}

cJSON* oxc_info_packet(oxc_device* p_oxc){
    cJSON* param = cJSON_CreateObject();    
    cJSON_AddItemToObject(param,"modelType",cJSON_CreateString(p_oxc->model_type));
    cJSON_AddItemToObject(param,"serialNumber",cJSON_CreateString(p_oxc->serial_number));
    cJSON_AddItemToObject(param,"softVersion",cJSON_CreateString(p_oxc->soft_version));
    cJSON_AddItemToObject(param,"mainVersion",cJSON_CreateString(main_firmware_version));               
    return param;  
}

cJSON* get_info_oxc(oxc_device* p_oxc){
    int ret;
    char buff[OXC_BUF_LENGTH] = {0};
 
    sprintf(buff,"*idn?");
    ret = query_tty((device*)p_oxc,buff,strlen(buff),buff,OXC_BUF_LENGTH,5,0);
    if(ret > 0){
        if(find_keys("[A-Za-z]+, *([a-zA-Z0-9-]+), *([0-9]+), *([0-9]+\\.[0-9]+\\.[0-9]+)",
                                buff,
                                3,
                                p_oxc->model_type,
                                p_oxc->serial_number,
                                p_oxc->soft_version)){               
            return oxc_packet(id_oxc_get_info,NO_ERROR,oxc_info_packet(p_oxc),0);            
        }        
    }            
    return oxc_packet(id_oxc_get_info,COMM_TIMEOUT,NULL,0);
}

cJSON* oxc_get_power_packet(oxc_device* p_oxc,char* s_power){
    int size;
    float powers[OXC_CHANNEL_NUMBER] = {0.0};
    string_to_array(s_power,powers,&size,1);

    cJSON* param = cJSON_CreateObject();    
    cJSON_AddItemToObject(param,"powerList",cJSON_CreateFloatArray(powers,size));             
    return param;     
}

cJSON* get_power_oxc(oxc_device* p_oxc,cJSON* param){
    cJSON* array,*item;
    int ret,size,i,j=0;
    int channels[OXC_CHANNEL_NUMBER]={0};
    char buff[OXC_BUF_LENGTH] = {0};
    char list[OXC_BUF_LENGTH] = {0};
    int b,e;
    array = cJSON_GetObjectItem(param,"channelList");
    size = cJSON_GetArraySize(array);
    for(i=0;i<size;i++){
        item = cJSON_GetArrayItem(array,i);
        if(item){
            channels[j++] = item->valueint;
        }
    }
    array_to_string(channels,j,0,list,0);
    sprintf(buff,":pmon:pow? (@%s);",list);    
    ret = query_tty((device*)p_oxc,buff,strlen(buff),buff,OXC_BUF_LENGTH,5,0);       
    if(ret > 0){
        if(find_key("\\(([0-9\\.,-]+)\\)",buff,&b,&e,1,1)){
            memmove(buff,buff+b,e-b);
            buff[e-b] = 0;                                        
            return oxc_packet(id_oxc_get_power,NO_ERROR,oxc_get_power_packet(p_oxc,buff),0);            
        }        
    }            
    return oxc_packet(id_oxc_get_power,COMM_TIMEOUT,NULL,0);       
}

void set_atten_table(oxc_device* p_oxc,int* channel_list,int size,float atten){
    int channel_num;
    int b,e,index=0,i;
    char buff[32];
    for(i=0;i<size;i++){
        if(channel_list[i]<=OXC_CHANNEL_NUMBER){
            p_oxc->atten_table[channel_list[i]-1] = atten;
        }
    }
    // oxc_save_config(p_oxc,0);    
}   

void sort_atten_table(atten_s* att_l,int l ,int r){
    atten_s temp;
    if (l < r){
        int i = l, j = r;
        memcpy(&temp,&att_l[l],sizeof(atten_s));
        while (i < j){
            while(i < j && att_l[j].atten >= temp.atten) j--;  
            if(i < j) memcpy(&att_l[i++],&att_l[j],sizeof(atten_s));
            
            while(i < j && att_l[i].atten < temp.atten) i++;                  
            if(i < j) memcpy(&att_l[j--],&att_l[i],sizeof(atten_s)); 
        }
        memcpy(&att_l[i],&temp,sizeof(atten_s));
        sort_atten_table(att_l, l, i - 1); // 递归调用 
        sort_atten_table(att_l, i + 1, r);
    }
}

int init_atten_abs(oxc_device* p_oxc){
    int i,j,count = 0;
    atten_s att_l[OXC_CHANNEL_NUMBER] = {0};
    int channels[OXC_CHANNEL_NUMBER] = {0};
    char buff[OXC_BUF_LENGTH] = {0};
    char temp[32] = {0};
    for(i=0;i<OXC_CHANNEL_NUMBER;i++){
        att_l[i].channel_num = i+1;
        att_l[i].atten = p_oxc->atten_table[i];
    }
    sort_atten_table(att_l,0,OXC_CHANNEL_NUMBER-1);

    for(i=0,j=0;i<OXC_CHANNEL_NUMBER;i++){
        if(i == 0){                        
            channels[j++] = att_l[i].channel_num;
        } 
        else{
            if(att_l[i].atten - att_l[i-1].atten < 1e-4){
                channels[j++] = att_l[i].channel_num;
            }
            else{
                set_atten_abs(p_oxc,channels,j,att_l[i-1].atten,NULL);
                j=0;
            }
        }
    }
    set_atten_abs(p_oxc,channels,j,att_l[i-1].atten,NULL);
    return 1;
}

int set_atten_abs(oxc_device* p_oxc,int* channel_list,int size,float atten,clock_t* p_time){
    char buff[OXC_BUF_LENGTH] = {0};
    char s_channel[OXC_BUF_LENGTH] = {0};
    int ret;
    array_to_string(channel_list,size,0,s_channel,0);
    sprintf(buff,":att:abs (@%s),%0.1f;*opc;*opc?",s_channel,atten);      
    ret = query_tty_time((device*)p_oxc,buff,strlen(buff),buff,OXC_BUF_LENGTH,5,0,p_time);
    if(ret > 0){
        if(find_key("1",buff,NULL,NULL,0,0)){                                  
            return 1;            
        }        
    }                  
    return 0;    
}

cJSON* set_atten_abs_oxc(oxc_device* p_oxc,cJSON* param){
    cJSON* item,*array;
    int ret,size,i,j=0;
    atten_s att_l[OXC_CHANNEL_NUMBER] = {0};
    int channels[OXC_CHANNEL_NUMBER] = {0};

    float atten;
    clock_t time; 

    array = cJSON_GetObjectItem(param,"channelList");
    size = cJSON_GetArraySize(array);
    for(i=0;i<size;i++){
        item = cJSON_GetArrayItem(array,i);
        if(item){
            att_l[i++].channel_num = item->valueint; 
        }
    }
    array = cJSON_GetObjectItem(param,"attenList");
    size = cJSON_GetArraySize(array);
    for(i=0;i<size;i++){
        item = cJSON_GetArrayItem(array,i);
        if(item){
            att_l[i++].atten = item->valueint; 
        }
    }
    sort_atten_table(att_l,0,size-1);

    for(i=0,j=0;i<size;i++){
        if(i == 0){                        
            channels[j++] = att_l[i].channel_num;
        } 
        else{
            if(att_l[i].atten - att_l[i-1].atten < 1e-4){
                channels[j++] = att_l[i].channel_num;
            }
            else{
                set_atten_abs(p_oxc,channels,j,att_l[i-1].atten,NULL);
                j=0;
            }
        }
    }
    set_atten_abs(p_oxc,channels,j,att_l[i-1].atten,NULL);
                 
    return oxc_packet(id_oxc_set_atten,NO_ERROR,NULL,0);       
}

cJSON* set_atten_ref_oxc(oxc_device* p_oxc,cJSON* param){
    cJSON* item;
    int ret;
    char buff[OXC_BUF_LENGTH] = {0};
    char *channel_list;
    float atten;
    char* ref_channel_list;
    clock_t time; 
    int b,e;

    item = cJSON_GetObjectItem(param,"channelList");
    channel_list = item->valuestring;
    item = cJSON_GetObjectItem(param,"atten");
    atten = item->valuedouble;
    item = cJSON_GetObjectItem(param,"refChannelList");
    ref_channel_list = item->valuestring;

    sprintf(buff,":att:rel (@%s),%0.1f,(@%s);*opc;*opc?",channel_list,atten,ref_channel_list);   
    ret = query_tty_time((device*)p_oxc,buff,strlen(buff),buff,OXC_BUF_LENGTH,5,0,&time);
    if(ret > 0){
        if(find_key("1",buff,NULL,NULL,0,0)){    
            stroe_config_oxc(p_oxc,OXC_CONFIG_FILE);                           
            return oxc_packet(id_oxc_set_atten,NO_ERROR,NULL,time);            
        }        
    }                  
    return oxc_packet(id_oxc_set_atten,COMM_TIMEOUT,NULL,0);       
}

cJSON* set_atten_oxc(oxc_device* p_oxc,cJSON* param){
    // cJSON* item;
    // char* type;

    // item = cJSON_GetObjectItem(param,"type");
    // type = item->valuestring;
    // if(strcmp(type,"ref") == 0){
    //     return set_atten_ref_oxc(p_oxc,param);
    // }
    // else if(strcmp(type,"abs") == 0){
        return set_atten_abs_oxc(p_oxc,param);
    // }

    // return oxc_packet(oxc_set_atten,MISSING_PARAM,NULL,0);     
}

cJSON* oxc_get_atten_packet(oxc_device* p_oxc,int* channel_list,int c_size,
                                                float* atten_list,int a_size){    
    cJSON* param = cJSON_CreateObject(); 

    cJSON_AddItemToObject(param,"channelList",cJSON_CreateIntArray(channel_list,c_size));
    cJSON_AddItemToObject(param,"attenList",cJSON_CreateFloatArray(atten_list,a_size));             
    return param;     
}

cJSON* get_atten_oxc(oxc_device* p_oxc,cJSON* param){
    cJSON* item,*array;
    int ret,size,i,j=0;
    int channels[OXC_CHANNEL_NUMBER];
    char buff[OXC_BUF_LENGTH] = {0};
    char channel_list[OXC_BUF_LENGTH] = {0};
    float atten_list[OXC_CHANNEL_NUMBER] = {0.0f};
    int b,e,index=0,offset = 0;
    char m[4],v[12],r[12];
    float atten;
    char values[256] = {0};

    array = cJSON_GetObjectItem(param,"channelList");
    if(array){
        size = cJSON_GetArraySize(array);
        for(i=0;i<size;i++){
            item = cJSON_GetArrayItem(array,i);
            if(item){
                channels[j++] = item->valueint;
            }
        }
    }
    array_to_string(channels,j,0,channel_list,0);
    sprintf(buff,":att:stat? (@%s)",channel_list);    
    ret = query_tty((device*)p_oxc,buff,strlen(buff),buff,OXC_BUF_LENGTH,5,0);
    if(ret > 0){
        if(find_key("\\(([0-9ANRFM\\* ,-\\.]*)\\)",buff,NULL,NULL,1,1)){   
            i = 0;         
            while((index = find_keys("([NARFM]) ([-0-9\\.\\*]+) ([0-9\\*]+)",buff+offset,3,m,v,r))>0){
                offset += index;
                if(m[0] != 'N' && m[0] != 'A'){
                    return oxc_packet(id_oxc_get_power,OXC_ATTN_NOT_ABS,NULL,0);
                }
                if(m[0] == 'N'){
                    atten_list[i++] = 0.0f;
                    
                }
                else if(m[0] == 'A'){                    
                    if(atten < 0.0f){
                        atten = strtof(v+1,NULL);                        
                    }
                    else{
                        atten = strtof(v,NULL);
                    }
                    atten_list[i++] = atten;                
                }
            }                                
            return oxc_packet(id_oxc_get_power,NO_ERROR,oxc_get_atten_packet(p_oxc,channels,j,atten_list,i),0);
        }
    }       
    return oxc_packet(id_oxc_set_atten,NO_ERROR,NULL,0);       
}

cJSON* reset_oxc(oxc_device* p_oxc){
    int ret;
    char send[OXC_BUF_LENGTH] = {0};
    char recv[OXC_BUF_LENGTH] = {0};

    sprintf(send,"*rst;*opc;*opc?");
    ret = query_tty((device*)p_oxc,send,strlen(send),recv,OXC_BUF_LENGTH,20,0);
    if(ret > 0){
        if(find_key("1",recv,NULL,NULL,0,0)){               
            return oxc_packet(id_oxc_reset,NO_ERROR,NULL,0);            
        }        
    }            
    return oxc_packet(id_oxc_reset,COMM_TIMEOUT,NULL,0);
}


//--------------------------

cJSON* oxc_parse(CMD_ID id,cJSON* param){
    cJSON* oxc_json = NULL;
    if(oxc.busy) {
        return oxc_packet(id,DEVICE_BUSY,NULL,0);
    }
    oxc.busy = 1;
    switch(id){
        case id_oxc_set_custom:	
            oxc_json = set_custom_oxc(&oxc,param);
        break;
        case id_oxc_get_custom:
            oxc_json = get_custom_oxc(&oxc);
        break;
        case id_oxc_reset:	
            oxc_json = reset_oxc(&oxc);
        break;
        case id_oxc_get_info:
            oxc_json = get_info_oxc(&oxc);
        break; 
        case id_oxc_get_power:
            oxc_json = get_power_oxc(&oxc,param);
        break;
        case id_oxc_set_atten:
            oxc_json = set_atten_oxc(&oxc,param);
        break;
        case id_oxc_get_atten:
            oxc_json = get_atten_oxc(&oxc,param);
        break;
        case id_save_default:
            // oxc_save_config(&oxc,1);
            stroe_config_oxc(&oxc,OXC_CONFIG_FILE_BACK);
            break;
        break;
        case id_load_default:
            // oxc_load_config(&oxc,1);
            load_config_oxc(&oxc,OXC_CONFIG_FILE_BACK);            
            break;
        break;
    }
    oxc.busy = 0; 
    return oxc_json;
   
}

/*
static void test(void){
    int ret;
    char *channel_list;
    int b,e,index = 0,offset = 0;;
    char m[4],v[12],r[12];
    float atten;
    char values[256] = {0};
    char buff[] = "(N -10.0 *,A -10.50 *,A -5.00 *)";
    if(find_key("\\(([0-9ANRFM\\* ,-\\.]*)\\)",buff,&b,&e,1,1)){            
        // strmove(buff,buff+b,e-b);   
        // offset = b;
        while((index = find_keys("([NARFM]) ([-0-9\\.\\*]+) ([0-9\\*]+)",buff+offset,3,m,v,r))>0){
            offset += index;
            if(m[0] != 'N' && m[0] != 'A'){
                // return oxc_packet(oxc_get_power,OXC_ATTN_NOT_ABS,NULL,0);
                continue;
            }
            if(m[0] == 'N'){
                sprintf(values+strlen(values),"0.0,");
            }
            else if(m[0] == 'A'){                    
                if(atten < 0.0f){
                    atten = strtof(v+1,NULL);                        
                }
                else{
                    atten = strtof(v,NULL);
                }
                sprintf(values+strlen(values),"%0.1f,",atten);                    
            }
        }
        if(strlen(values) > 0){
            values[strlen(values)-1] = 0;
        }      
    }
    printf("%s\n",values);
}
*/
static void test(){
    char test[128] = "12,1,56,12,4,34,1,4,124,4,1,252";
    char f_test[128] = "12.9,1.0,56.242,12.7,4.9,34.00,1,4.4,124.49,4.51,1.0,252.0";
    int port[32] = {0};
    float atten[32] = {0.0f};
    int size,i;
    // string_to_array(test,port,&size,0);
    // printf("size if %d\n",size);
    // for(i=0;i<32;i++){
    //     printf("port[%d] = %d\n",i,port[i]);
    // }
    // memset(test,0,128);
    // array_to_string(port,size,0,test,0);
    // printf("test is %s\n",test);
    string_to_array(f_test,atten,&size,1);
    printf("size if %d\n",size);
    for(i=0;i<32;i++){
        printf("port[%d] = %0.1f\n",i,atten[i]);
    }
    memset(test,0,128);
    array_to_string(atten,size,1,test,1);
    printf("test is %s\n",test);

    cJSON* array = cJSON_CreateFloatArray(atten,size);
    char* p = cJSON_Print(array);
    printf(p);
    free(p);
}

void* oxc_thread(void* param){    
    init_oxc(&oxc);    
    init_oxc_device(&oxc);
    // test();
    while(!oxc.exit){
        if(oxc.sample_flag){            
            if(oxc.busy) continue;
            oxc.sample_flag = 0;
            oxc_sample(&oxc);      
        }
        usleep(50*1000);
    }    
    return NULL;
}